﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using org.pdfbox.pdmodel;
using org.pdfbox.util;
using Microsoft.Office.Interop.Excel;
using System.Reflection;
using org.pdfbox;
using Excel = Microsoft.Office.Interop.Excel;
using System.Data.SqlClient;
using System.Runtime.InteropServices;

namespace EAreader
{
    public interface EApdfreader
    {
        int ParseEvents(int len1, IntPtr FileName);

        int GetNumberOfTables();

        int GetNumberOfEventsInTable(int table);

        void GetEventStart(int Length, int tableNum, int eventNum,
            [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] StartTime);

        void GetEventDuration(int Length, int tableNum, int eventNum,
            [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] Duration);

        int GetEventSeverity(int tableNum, int eventNum);
        
    }

    public class EA_reader : EApdfreader
    {
        private string[][][] EvList = null;

        private List<int> EventNumber = new List<int>();
        private List<int> EventSeverity = new List<int>();

        private void FindNotNullId(int tableNum,  int eventNum, out int tableId, out int eventId)
        {
            tableId = 0;
            int Id = 0;
            tableId += Convert.ToInt32(EvList[Id]!=null);
            while ((tableId < tableNum) && (Id < EvList.Length))
            {
                Id++;
                tableId += Convert.ToInt32(EvList[Id]!=null);   
            }
            tableId = Id;
            string[][] tmp = EvList[Id];
            eventId = 0;
            Id = 0;
            eventId = Convert.ToInt32(tmp[Id] != null);
            while ((eventId < eventNum) && (Id < EvList[tableId].Length))
            {
                Id++;
                eventId += Convert.ToInt32(tmp[Id] != null);
            }
            eventId = Id;
        }

        public int ParseEvents(int len1, IntPtr FileName)
        {
            string FileNm = Marshal.PtrToStringAnsi(FileName);
            string content = parseUsingPDFBox(FileNm);
            ProcessEvents(content);
            return 0;
        }

        public int GetNumberOfTables()
        {
            int res = 0;
            if (EvList != null)
            {
                for (int i = 0; i < EvList.Length; i++)
                {
                    res += Convert.ToInt32(EvList[i] != null);
                }
            }
            return res;
        }

        public int GetNumberOfEventsInTable(int table)
        {
            int res = 0;
            string [][] tmp = EvList[table-1];
            if (tmp != null)
            {
                for (int i = 0; i < tmp.Length; i++)
                {
                    res += Convert.ToInt32(tmp[i] != null);
                }
            }
            return res;
        }

        public void GetEventStart(int Length, int tableNum, int eventNum,
            [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] StartTime)
        {
            int eventId;
            int tableId;
            FindNotNullId(tableNum, eventNum, out tableId, out eventId);
            string[] EventDescr = EvList[tableId][eventId];
            StartTime[0] = Convert.ToInt32(EventDescr[1]);
            StartTime[1] = Convert.ToInt32(EventDescr[2]);
            StartTime[2] = Convert.ToInt32(EventDescr[3]);
            //Duration[0] = Convert.ToInt32(EventDescr[4]);
            //Duration[1] = Convert.ToInt32(EventDescr[5]);
            //Duration[2] = Convert.ToInt32(EventDescr[6]);
        }

        public void GetEventDuration(int Length, int tableNum, int eventNum,
    [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] Duration)
        {
            int eventId;
            int tableId;
            FindNotNullId(tableNum, eventNum, out tableId, out eventId);
            string[] EventDescr = EvList[tableId][eventId];
            //StartTime[0] = Convert.ToInt32(EventDescr[1]);
            //StartTime[1] = Convert.ToInt32(EventDescr[2]);
            //StartTime[2] = Convert.ToInt32(EventDescr[3]);
            Duration[0] = Convert.ToInt32(EventDescr[4]);
            Duration[1] = Convert.ToInt32(EventDescr[5]);
            Duration[2] = Convert.ToInt32(EventDescr[6]);
        }

        public static string parseUsingPDFBox(string input)
        {
            PDDocument doc = PDDocument.load(input);
            PDFTextStripper stripper = new PDFTextStripper();
            PDPage active_page = new PDPage();
            string S = doc.toString();
            return stripper.getText(doc);
        }

        public string[][][] Parse_Events(string[][] tables)
        {
            char[] year = new char[4];
            char[] month = new char[2];
            char[] day = new char[2];
            char[] exemp = new char[4];
            char[] exemp2 = new char[2];
            int i = 0;
            int j = 0;
            string[] result = new string[11];
            string[][][] AllResults = new string[tables.Length][][];
            foreach (string[] events in tables)
            {

                //result_text.Text = "****************";
                AllResults[i] = new string[events.Length][];
                for (j = 0; j < events.Length; j++)
                {
                    if (events[j] != "" && events[j] != null)
                    {
                        if (events[j][23] == ')' && events[j][14] == '(' && events[j][4] == ' ')
                        {

                            events[j].CopyTo(0, exemp, 0, 4);//ID
                            string str = new string(exemp);
                            result[0] = str;

                            events[j].CopyTo(5, exemp2, 0, 2);//Start hour
                            result[1] = new string(exemp2);

                            events[j].CopyTo(8, exemp2, 0, 2);//Start minutes
                            result[2] = new string(exemp2);

                            events[j].CopyTo(11, exemp2, 0, 2);//Start seconds
                            result[3] = new string(exemp2);

                            events[j].CopyTo(15, exemp2, 0, 2);//Duration hour
                            result[4] = new string(exemp2);

                            events[j].CopyTo(18, exemp2, 0, 2);//Duration minutes
                            result[5] = new string(exemp2);

                            events[j].CopyTo(21, exemp2, 0, 2);//Duration seconds
                            result[6] = new string(exemp2);

                            result[10] = "1";
                            AllResults[i][j] = new string[11];
                            Array.Copy(result, 0, AllResults[i][j], 0, 11);
                        } //Конец проверки формата строки

                        // AllResults[i][j] = new (string[])result.clone();


                    }
                    else
                        AllResults[i][j] = null;
                }
                i++;
            }
            return AllResults;
        }

        public static string[][][] getEvents(string content)
        {
            int x = 0;
            int y = 0;
            int z = 0;
            char[] buf = new char[24];
            string[] res;
            int delta;

            res = content.Split(new string[] { "СКАТ (ЭА \"Ту-2" }, StringSplitOptions.None);
            char[] table_name;
            string[] t_name = new string[res.Length];
            t_name[0] = null;
            for (int i = 1; i < res.Length; i++)
            {
                //table_name= res[i].Split(new string[] { "Рег" }, StringSplitOptions.None);
                //char[] table_name[0] = new char[res[i].IndexOf("Рег") + 1];
                table_name = new char[res[i].IndexOf("Рег") + 1];
                res[i].CopyTo(0, table_name, 0, res[i].IndexOf("Рег"));

                t_name[i] = new string(table_name);
                string[] buf_string = res[i].Split(new string[] { "сообщений и параметры" }, StringSplitOptions.None);
                res[i] = buf_string[1];
                buf_string = res[i].Split(new string[] { "Экспресс анализ проведен" }, StringSplitOptions.None);
                res[i] = buf_string[0];
            }
            string[][] events = new string[res.Length][];
            for (int i = 0; i < res.Length; i++)
            {
                events[i] = res[i].Split(new string[] { "\r\n" }, StringSplitOptions.None);
                for (int j = 0; j < events[i].Length; j++)
                {
                    if (events[i][j].Length > 26)
                    {
                        delta = 0;
                        if (events[i][j][0] == '\r')

                            delta = 2;
                        events[i][j].CopyTo(delta, buf, 0, 24);
                        events[i][j] = "";
                        if (buf.Length > 0)
                            if (buf[0] == '0' || buf[0] == '1')
                                for (int p = 0; p < 24; p++)
                                {
                                    events[i][j] += buf[p];
                                }
                    }
                    else events[i][j] = "";
                }
            }
            z = 11;
            char[] exemp = new char[4];
            char[] exemp2 = new char[2];
            x = 0;
            y = 0;
            string[][][] result = new string[2][][];
            result[0] = events;
            result[1] = new string[1][];
            result[1][0] = t_name;
            return result;
        }

        public void ProcessEvents(string content)
        {
            string [][][] EvListNP = getEvents(content);
            EvList = Parse_Events(EvListNP[0]);
            UploadEventDataXLS();
        }

        public int Add(int b, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] u)
        {
            u[0] = 10;
            return u[0] + u[1];
        }

        public int GetEventSeverity(int tableNum, int eventNum)
        {
            int result = 0;
            int eventId;
            int tableId;
            FindNotNullId(tableNum, eventNum, out tableId, out eventId);
            int id = Convert.ToInt32(EvList[tableId][eventId][0]);
            int Index = EventNumber.IndexOf(id);
            if (Index > 0)
            {
                result = EventSeverity[Index];
            }
            return result; 
        }

        private int RiskEvent(string input)
        {
            int i = 0;
            if (input == "Предупреждающее")
            {
                i = 1;
            }
            if (input == "Опасное")
            {
                i = 2;
            }
            return i;
        }

        private void UploadEventDataXLS()
        {
            Excel.Application xlApp;
            Excel.Workbook xlWorkBook = null;
            Excel.Worksheet xlWorkSheet = null;
            Excel.Range range;
            int str;
            int Severity;
            int rCnt = 0;
            int cCnt = 0;
            try
            {
                string[] lines = System.IO.File.ReadAllLines("configEA.txt");
                xlApp = new Excel.Application();
                xlWorkBook =
                    xlApp.Workbooks.Open(lines[0]);
                xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
                range = xlWorkSheet.UsedRange;
                for (rCnt = 1; rCnt <= range.Rows.Count; rCnt++)
                {
                    str = Convert.ToInt32(range.Value2[rCnt, 1]);
                    Severity = RiskEvent((string)(range.Cells[rCnt, 3] as Excel.Range).Value2);
                    EventNumber.Add(str);
                    EventSeverity.Add(Severity);
                }
                xlWorkBook.Close();
            }
            catch (Exception ex)
            {
                int k = 1 / 2;
                throw ex;
            }
        }
    }
}
